package com.miku.config;

import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;


@Configuration
@Data
public class ThreadPoolExecutorConfig {


    /**
     * 核心线程数
     */
    private int corePoolSize=2;

    /**
     * 最大线程数
     */
    private int maximumPoolSize=4;

    /**
     * 线程存活时间
     */
    private long keepAliveTime=100;


    /**
     * 创建线程池
     * int corePoolSize- 核心线程数
     * int maximumPoolSize- 最大线程数
     * long keepAliveTime- 线程存活时间
     * TimeUnit unit- 时间单位
     * BlockingQueue<Runnable> workQueue- 任务队列
     * ThreadFactory threadFactory- 线程工厂
     * RejectedExecutionHandler handler- 拒绝策略
     * @return
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(){
        ThreadFactory threadFactory=new ThreadFactory() {
            private int count=1;
            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread=new Thread(r);
                thread.setName("线程:"+count);
                count++;
                return thread;
            }
        };
        //
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), threadFactory);
    }

    @Bean
    public ListeningScheduledExecutorService listeningScheduledExecutorService(ThreadPoolExecutor threadPoolExecutor) {
        return MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(corePoolSize));
    }


    // 使用Guava进行异步重试的示例方法

    /**
     * 使用Guava进行异步重试的示例方法
     * @param service- ListeningScheduledExecutorService 实例
     * @param task- 需要执行的任务
     * @param maxRetries- 最大重试次数
     * @param delayMillis- 重试间隔时间（毫秒）
     */
    public void executeWithRetry(ListeningScheduledExecutorService service, Runnable task, int maxRetries, long delayMillis) {
        service.submit(() -> {
            boolean success = false;
            int attempts = 0;
            while (!success && attempts < maxRetries) {
                try {
                    task.run();
                    success = true;
                } catch (Exception e) {
                    attempts++;
                    System.out.println("任务执行失败，正在进行第 " + attempts + " 次重试");
                    if (attempts >= maxRetries) {
                        System.out.println("达到最大重试次数，任务执行失败");
                        break;
                    }
                    // 安排下一次重试
                    service.schedule(() -> {
                        task.run();
                    }, delayMillis, TimeUnit.MILLISECONDS);
                }
            }
        });
    }
}
